package com.weishenai.Utils;

import com.weishenai.Annotation.priMaryKey;
import com.weishenai.Annotation.tableName;
import org.junit.Test;

import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class CommonUtils {
    private static Object getFieldValueByName(String fieldName, Object o) {
        try {
            String firstLetter = fieldName.substring(0, 1).toUpperCase();
            String getter = "get" + firstLetter + fieldName.substring(1);
            Method method = o.getClass().getMethod(getter, new Class[]{});
            Object value = method.invoke(o, null);
            return value;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    private static Object[] getFieldValues(Object o) {
        List<Object> params = new ArrayList<>();
        Class aClass = o.getClass();
        Field[] fields = aClass.getDeclaredFields();
        for (Field field : fields) {
            Object param = getFieldValueByName(getField_Name(field.getName()), o);
            params.add(param);
        }
        return params.toArray();
    }

    /**
     * @Description: 驼峰与短杠转变
     * @Param: [fieldName]
     * @return: java.lang.String
     * @Author: weishenai
     * @Date: 2021/10/8
     */
    private static String getField_Name(String fieldName) {
        Pattern humpPattern = Pattern.compile("[A-Z]");
        Matcher matcher = humpPattern.matcher(fieldName);
        StringBuffer sb = new StringBuffer();
        while (matcher.find()) {
            matcher.appendReplacement(sb, "_" + matcher.group(0).toLowerCase());
        }
        matcher.appendTail(sb);
        return sb.toString();
    }

    public static Object[] getArrayParams(Object o) {
        return getFieldValues(o);
    }

    public static Map<String, Object> getMapParams(Object o) {
        Map<String, Object> pa = new HashMap<>();
        Class aClass = o.getClass();
        Field[] fields = aClass.getDeclaredFields();
        for (Field field : fields) {
            Object param = getFieldValueByName(field.getName(), o);
            pa.put(getField_Name(field.getName()), param);
        }
        return pa;
    }

    public static List<Map<String, Object>> getFieldAndValues(Object o) {
        List<Map<String, Object>> res = new ArrayList<>();
        Class aClass = o.getClass();
        Field[] fields = aClass.getDeclaredFields();
        for (Field field : fields) {
            Map<String, Object> keyValue = new HashMap<>();
            Object param = getFieldValueByName(field.getName(), o);
            keyValue.put("fieldName", getField_Name(field.getName()));
            keyValue.put("value", param);
            res.add(keyValue);
        }
        return res;
    }

    public static String getTableName(Object o) {
        return o.getClass().getAnnotation(tableName.class).value();
    }

    public static Map<String, Object> getPrimaryKey(Object o) {
        Map<String, Object> priMaryKey = new HashMap<>();
        Class aClass = o.getClass();
        Field[] fields = aClass.getDeclaredFields();
        for (Field field : fields) {
            if (field.getAnnotation(priMaryKey.class) != null) {
                priMaryKey.put("priMaryKeyName", field.getAnnotation(priMaryKey.class).value());
                priMaryKey.put("priMaryKeyValue", getFieldValueByName(getField_Name(field.getName()), o));
            }
        }
        if (priMaryKey.isEmpty()) {
            priMaryKey.put("priMaryKeyName", "id");
            priMaryKey.put("priMaryKeyValue", getFieldValueByName("id", o));
        }
        return priMaryKey;
    }


}
